package controllers.wiki;

import controllers.Application;
import controllers.MailSender;
import jobs.SenderJob;
import models.ApplicationUser;
import models.wiki.Page;
import models.wiki.TagCloud;
import play.data.binding.types.DateBinder;
import play.db.jpa.GenericModel;
import play.jobs.Job;
import play.mvc.Before;
import play.mvc.Controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @author Valentin.Kononov
 */
public class WikiController extends Controller {
    private  static int lastUnnamed = 0;


    @Before(unless = {"login", "authenticate"})
    static void checkAuthentication() {
        if (!session.contains("uid")) {
            session.clear();
            Application.login();
        }
        ApplicationUser user = ApplicationUser.findById(Long.parseLong(session.get("uid")));
        if (user == null) {
            session.clear();
            Application.login();
        }
    }

    public static void deleteAll() {
        Page.deleteAll();
    }

    private static int topManyCount = 15;
    private static int topShortCount = 4;

    public static void index() {
        List<Page> allPages = Page.find("order by createdDate desc").fetch();
        List<Page> topManyList = allPages.subList(0, Math.min(topManyCount, allPages.size()));
        List<Page> topShortList = allPages.subList(0, Math.min(topShortCount, allPages.size()));

        List<TagCloud> tagsList = TagCloud.findAll();

        if(tagsList.size() == 0){
            fetchTags(allPages);
            tagsList = TagCloud.findAll();
        }

        render(topManyList, topShortList, tagsList);
    }

    private static void fetchTags(List<Page> allPages) {
        TagCloud.deleteAll();
        //get all possible tags;
        for(int i = 0;i<allPages.size();i++){
            Page current = allPages.get(i);
            if(current.tags != null && current.tags.length > 0){
                for(int j = 0;j<current.tags.length;j++) {
                    TagCloud tag = TagCloud.find("byName", current.tags[j]).first();
                    if(tag != null){
                        tag.weight++;
                        tag.save();
                    }
                    else {
                        tag = new TagCloud(current.tags[j], 1);
                        tag.save();
                    }
                }
            }
        }
    }

    public static void currentWiki(String name) {
        Page current = Page.find("byName", name).first();
        //lastUnnamed--;
        render(current);
    }

    public static void currentWikiByID(Long id) {
        Page current = Page.findById(id);
        //lastUnnamed--;
        render(current);
    }

    public static void saveNewPage(String name, String content) {
        //получение id пользователя, создавшего статью

        Page current = new Page();
        if (name == null) {
            name = "unnamed_" + lastUnnamed++;
            content = "";
        }
        current.name = name;
        current.content = content;
        current.author_id = session.get("uid");
        current.last_modifier_id = current.author_id;
        current.createdDate = new Date();
        current.lastEditedDate = current.createdDate;

        current.save();

        //todo: correct tags update process
        List<Page> allPages = Page.findAll();
        fetchTags(allPages);

        //render new page template
        currentWiki(current.name);
    }

    public static void checkUniqueName(String name, Long id)
    {

        Page page = Page.find("byName", name).first();
        boolean existName = page != null;

        if (page != null) {
            if (page.id != id) {
                existName = true;
            } else {
                existName = false;
            }
        }
        render(existName);
    }

    public static void updatePage(Long id, String name, String summary, String content, String tags) {
        Page page = Page.findById(id);
        page.name = name;
        page.summary = summary;
        page.content = content;
        page.lastEditedDate = new Date();

        page.tags = tags.split("\\;|\\,");  //todo: check regular expression

        page.last_modifier_id = session.get("uid");
        page.lastEditedDate = new Date();

        for(int i = 0;i<page.tags.length;i++){
            page.tags[i] = page.tags[i].trim();
        }

        if(!page.author_id.equals(page.last_modifier_id)) {
            //run sending message in the separate thread to let the user continue work without waiting
            SenderJob sJob = new SenderJob(page.author_id, page.last_modifier_id);
            sJob.now();
        }

        page.save();

        //todo: correct tags update process
        List<Page> allPages = Page.findAll();
        fetchTags(allPages);

        //currentWiki(name);
    }

    public static void update(Long id, String name, String content) {
        Page page = Page.findById(id);
        page.name = name;
        page.content = content;
        currentWiki(name);

    }
    public static void deletePage(Long id) {
        Page page = Page.findById(id);
        page.delete();
    }

    public static void showPage(Long id) {
        Page page = Page.findById(id);
        //page.name = name;
        //page.content = page.getHtmlContent(markDownProcessor, page.content);

        ApplicationUser author = ApplicationUser.findById(Long.parseLong(page.author_id));
        String authorName = author.name;

        render(page, authorName);
    }
    
    public static void listByTag(String tag) {
        List<Page> allPages = Page.findAll();
        List<Page> result = new ArrayList<Page>();
        int size = allPages.size();
        for(int i = 0; i< size;i++){
            Page current = allPages.get(i);
            if(current.tags != null) {
                List<String> tagsList = Arrays.asList(current.tags);
                if(tagsList.contains((tag))){
                    result.add(current);
                }
            }
        }

        //List<Page> allPages = Page.find("byTags", tag).fetch();
        render(result);
    }

    public static void articleList()
    {
        List<Page> allPages = Page.findAll();
        render(allPages);
    }
}
